{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Tutorial for using the Crowd Counting APIs\n",
    "\n",
    "Start by importing the crowdcunting package and other packages."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import os\n",
    "import sys\n",
    "from crowdcounting import CrowdCountModelPose, CrowdCountModelMCNN, Router\n",
    "import urllib\n",
    "import base64\n",
    "import io\n",
    "from PIL import Image\n",
    "from matplotlib.pyplot import imshow\n",
    "import numpy as np\n",
    "%matplotlib inline"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Let's look at the example image, courtesy of Satria Perkasa on Unsplash. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "img = '../data/images/1.jpg'\n",
    "pil_im = Image.open(img)\n",
    "imshow(np.asarray(pil_im))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Here we load the model and make predictions. By default, we used the CrowdCountModlePose() function which uses OpenPose model as implemented by [this GitHub repo](https://github.com/jiajunhua/ildoonet-tf-pose-estimation). \n",
    "\n",
    "Another option is the CrowdCountModelMCNN() function which uses the MCNN model as implemented [here](https://github.com/svishwa/crowdcount-mcnn).\n",
    "\n",
    "The last option is the Router() function is is a combination of the above two functions. Specifically, it uses the prediction from OpenPose unless both predictions from OpenPose and MCNN exceed predefined cutoff point. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "mcnn_model_path = '../data/models/mcnn_shtechA_660.h5'\n",
    "\n",
    "gpu_id = 0\n",
    "model = CrowdCountModelPose(gpu_id)\n",
    "# model = CrowdCountModelMCNN(gpu_id, model_path=mcnn_model_path)\n",
    "# model = Router(gpu_id, mcnn_model_path=mcnn_model_path, cutoff_pose=20, cutoff_mcnn=50)\n",
    "\n",
    "with open(img, 'rb') as image:\n",
    "    b = image.read()\n",
    "    result = model.score(b, return_image=True, img_dim=1750)\n",
    "\n",
    "pred = result[\"pred\"]\n",
    "scored_image = result[\"image\"]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Here we convert the scored image into Pillow image format."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "scored_image = urllib.parse.unquote(scored_image)\n",
    "scored_image = base64.b64decode(scored_image)\n",
    "scored_image = Image.open(io.BytesIO(scored_image))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Finally we can show the scored image."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "imshow(np.asarray(scored_image))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Feel free to try the other two models - CrowdCountModelMCNN and Router - and compare the results.\n",
    "You can also set up a web service by using the code in the crowdcounting/demo folder."
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
